package com.uusoft.core.utils.xml;

import java.io.InputStream;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.sax.SAXSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import com.uusoft.core.exception.CommException;
import com.uusoft.core.utils.IOUtils;

/**
 * 使用XSD文件校验xml配置文件
 * 
 * @author shisheng.lian
 * 
 */
public class XsdXmlValidate implements XmlValidate {

	private InputStream configInputStream;
	private String xsdFileLocation;

	public XsdXmlValidate(InputStream configInputStream, String xsdFileLocation) {
		this.configInputStream = configInputStream;
		this.xsdFileLocation = xsdFileLocation;
	}

	public void validateXML() throws CommException {
		InputStream xsdInputStream = null;
		try {
			xsdInputStream = this.getClass().getResourceAsStream(
					xsdFileLocation);
			if (xsdInputStream == null) {
				throw new IllegalArgumentException("can not find resource["
						+ xsdFileLocation + "]");
			}
			
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			factory.setNamespaceAware(true);
			SchemaFactory schemaFactory = SchemaFactory
					.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
			Schema schema = schemaFactory.newSchema(new SAXSource(new InputSource(
					xsdInputStream)));
			factory.setSchema(schema);
			
			DocumentBuilder builder = factory.newDocumentBuilder();
			
			builder.setErrorHandler(new ErrorHandler() {
				
				public void warning(SAXParseException exception)
						throws SAXException {
					throw new CommException(exception);
				}
				
				public void fatalError(SAXParseException exception)
						throws SAXException {
					throw new CommException(exception);
				}
				
				public void error(SAXParseException exception) throws SAXException {
					throw new CommException(exception);
				}
			});
			builder.parse(configInputStream);
		} catch (Exception e) {
			throw new CommException(e);
		} finally {
			IOUtils.closeQuietly(xsdInputStream);
			IOUtils.closeQuietly(configInputStream);
		}
	}
}
